<template>
  <div>
    <el-table :data="model" ref="table" v-bind="$attrs" v-on="$listeners" >
      <template v-for="(item,index) in options">
        <template v-if="!item.headHidden">
          <el-table-column v-bind="item" v-if="item.type === 'index'"></el-table-column>
          <el-table-column v-bind="item" v-else>
              <template v-slot:header>
                <label v-if="item.prop" class="table-label">
                  <span class="require" v-if="required(item.prop)">*</span>
                  <span class="page-form-item-label__text">{{item.label}}</span>
                </label>
              </template>
              <template slot-scope="scope" >
                <template v-if="item.prop && item.prop.indexOf('.')>=0">
                  <form-item
                    v-bind="item"
                    :dynamicOptions="$attrs.dynamicOptions"
                    :dynamicDisabled="$attrs.dynamicDisabled"
                    :params="$attrs.dynamicParams || item.params"
                    v-on="$listeners"
                    :value="getProperty(model[scope.$index],item)"
                    :rules="item.rules || rules[item.prop]"
                    :clearable="item['clearable']==undefined?true:item['clearable']"
                    :cellInput="cellInput"
                    :disabled="item.disabled || !editable"
                    @input="handleInput($event, item.prop,model)"
                    :key="index"
                  >
                    <template v-if="item.type==='slot'">
                      <div :slot="item.prop" >
                        <slot :name="item.prop" :row="scope.row" :$index="scope.$index"></slot>
                      </div>
                    </template>
                  </form-item>
                </template>
                <template v-else>
                  <form-item
                    v-bind="item"
                    :dynamicOptions="$attrs.dynamicOptions"
                    :dynamicDisabled="$attrs.dynamicDisabled"
                    :params="$attrs.dynamicParams || item.params"
                    v-on="$listeners"
                    v-model="scope.row[item.prop]"
                    :rules="item.rules || rules[item.prop]"
                    :clearable="item['clearable']==undefined?true:item['clearable']"
                    :cellInput="cellInput"
                    :disabled="item.disabled || !editable"
                    @input="handleInput($event, item.prop,model)"
                    :key="index"
                  >
                    <template v-if="item.type==='slot'">
                      <div :slot="item.prop" >
                        <slot :name="item.prop" :row="scope.row" :$index="scope.$index"></slot>
                      </div>
                    </template>
                  </form-item>
                </template>
              </template>
          </el-table-column>
        </template>
      </template>
    </el-table>
    <el-pagination
      :style="paginationStyle"
      :align="paginationAlign"
      v-if="isPage"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="page.pageNum"
      :page-sizes="pageSizes"
      :page-size="page.pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="page.total">
    </el-pagination>
  </div>
</template>

<script>
  import FormItem from "./zb-formlist-item";
  import { Subject } from "rxjs";
  import deepClone from "../../../../utils/function/deepClone";

  export default {
    name:'ZbFormList',
    components: {
      FormItem,
    },
    props: {
      labelWidth: [Number, String],
      rmBottomBorder: {
        type: Boolean,
        default: false,
      },
      // 是否分页，true:是，false:否
      isPage:{
        type: Boolean,
        default: true,
      },
      // 分页的参数
      page:{
        type: Object,
        default: ()=>{
          return {
            pageSize:20,
            pageNum:1,
            total:0,
          }
        }
      },
      // 搜索的条件
      searchParams:{
        type: [Object,null,Array],
        default: ()=>{}
      },
      // 分页的风格格式
      paginationStyle:{
        type: String,
        default: 'padding: 20px;',
      },
      // 分页的 align
      paginationAlign:{
        type: String,
        default: 'right',
      },
      // 所有的页
      pageSizes:{
        type: Array,
        default: ()=>{
          return [20, 60, 90, 120, 200, 300]
        }
      },
      model: {
        type: [Array],
        default:()=>[]
      },
      rules: {
        type: Object,
        default() {
          return {};
        },
      },
      options: {
        type: [Array,Object],
        default:()=>{}
      },
      editable: {
        type: Boolean,
        default: true,
      },
      status:{
        type: String,
        default: "",
      },
      cellInput: Boolean,
      enableValidate: Boolean,
    },
    provide() {
      return {
        labelWidth: this.labelWidth,
        rules: this.rules,
        formSubject: this.formSubject,
      };
    },
    data() {
      return {
        validateMsgs: {},
        relationMap: new Map(),
        formSubject: new Subject(),
        formRules: {},
        cascadeMap: new Map(),
        hasInitOptionsProps: [],
      };
    },
    watch: {
      model: {
        handler(val) {
          if (val) {
            this.$nextTick(() => {
              this.$nextTick(() => {
                this.formRules = this.rules;
              });
            });
          }
          Object.keys(val).forEach((i) => {
            if (this.relationMap.has(i)) {
              const arr = this.relationMap.get(i);
              arr.forEach((itm) => {
                if (
                  val[i] === 0 ||
                  val[i] == null ||
                  val[i] === undefined ||
                  val[i] === ""
                ) {
                  if (this.model[itm.prop]) {
                    this.$set(this.model, itm.prop, "");
                  }
                  this.options[itm.index].disabled = true;
                  this.$nextTick(() => {
                    this.$delete(this.rules, itm.prop);
                    this.clearValidate(itm.prop);
                  });
                } else {
                  this.options[itm.index].disabled = false;
                  this.$nextTick(() => {
                    if (["number", "temperature"].includes(itm.type)) {
                      this.$set(this.rules, itm.prop, [
                        {
                          type: "number",
                          required: true,
                          message: itm.label + "不能为空",
                          trigger: "blur",
                          transform(value) {
                            return parseFloat(value);
                          },
                        },
                      ]);
                    } else {
                      this.$set(this.rules, itm.prop, [
                        {
                          required: true,
                          message: itm.label + "不能为空",
                          trigger: ["blur", "change"],
                        },
                      ]);
                    }
                  });
                }
              });
            }
            this.initCascadeOptions(val[i], i);
          });
        },
        deep: true,
        immediate: true,
      },
    },
    created() {
      // 获取列表数据
      if (!this.$listeners.getList){
        return this.$message.error('请先通过 @getList 事件来获取列表')
      }
      this.getList()

      if (!Object.keys(this.model).length) {
        this.formRules = this.rules;
      }
      //console.log("this.options:",this.options);
      this.options.forEach((i, index) => {
        //debugger;
        // 关联启用禁用
        if (i.hasOwnProperty("relation")) {
          const obj = {
            prop: i.prop,
            index: index,
            label: i.label,
            type: i.type,
          };
          i.disabled = true;
          if (this.relationMap.has(i.relation)) {
            const arr = this.relationMap.get(i.relation);
            if (arr.findIndex((itm) => itm.index === i.index) === -1) {
              arr.push(obj);
              this.relationMap.set(i.relation, arr);
            }
          } else {
            this.relationMap.set(i.relation, [obj]);
          }
        }
        if (i.hasOwnProperty("cascade")) {
          let parentField = "";
          if (i.params) {
            Object.keys(i.params).forEach((itm) => {
              if (!i.params[itm]) {
                parentField = itm;
              }
            });
          }
          const obj = {
            prop: i.prop,
            index: index,
            label: i.label,
            type: i.type,
            url: i.url,
            multiple: i.multiple,
            parentField,
          };
          if (this.cascadeMap.has(i.cascade)) {
            const arr = this.cascadeMap.get(i.cascade);
            if (arr.findIndex((itm) => itm.index === i.index) === -1) {
              arr.push(obj);
              this.cascadeMap.set(i.cascade, arr);
            }
          } else {
            this.cascadeMap.set(i.cascade, [obj]);
          }
        }
      });

    },
    methods: {
      handleSizeChange(val) {
        this.$emit('afterSizeChange',  this.page,this.searchParams)
        this.page.pageSize = val
        this.getList()
      },
      handleCurrentChange(val) {
        this.$emit('afterCurrentChange',  this.page,this.searchParams)
        this.page.pageNum = val
        this.getList()
      },
      getList(){
        this.$emit('getList',  this.page,this.searchParams)
      },
      required(prop) {
        const ruleData = this.rules[prop];
        let rq = false;
        if (!ruleData) {
          return rq;
        }
        ruleData.forEach((item) => {
          if (item.required) {
            rq = true;
          }
        });
        return rq;
      },
      getProperty(model,item){
        let aArr = item.prop.split('.')
        let tem = ''
        for (let i = 0; i < aArr.length; i++) {
          tem += `['${aArr[i]}']`
        }
        try {
          return eval(`model${tem}`)
        }catch (e) {
        }
      },
      onSubmit() {
        return false;
      },

      validate(fn) {
        this.$refs.Form.validate(fn);
      },
      resetFields() {
        this.$refs.Form.resetFields();
        this.formSubject.next({
          prop: "all",
          msgStatus: true,
          validateMessage: "",
        });
      },
      validate2(prop, msgStatus, validateMessage) {
        this.formSubject.next({ prop, msgStatus, validateMessage });
      },
      clearValidate(prop) {
        if (prop) {
          this.$refs.Form.clearValidate(prop);
          this.formSubject.next({ prop, msgStatus: true, validateMessage: "" });
        } else {
          this.$refs.Form.clearValidate();
          this.formSubject.next({
            prop: "all",
            msgStatus: true,
            validateMessage: "",
          });
        }
      },
      handleInput(val, key,model) {
        this.change(model,key,val)
        this.$emit("input", val, key);
        this.handlerCascade(val, key);
        // 强制更新
        this.$forceUpdate()
      },
      change(model,prop, val) {
        let aArr = prop.split('.')
        let tem = ''
        for (let i = 0; i < aArr.length; i++) {
          tem += `['${aArr[i]}']`
        }
        try {
          if (typeof(val)==='string') eval(`model${tem}='${val}'`)
          else eval(`model${tem}=${val}`)
        }catch (e) {
        }
      },
      // 选项级联处理
      handlerCascade(val, key) {
        if (this.cascadeMap.has(key)) {
          const arr = this.cascadeMap.get(key);
          arr.forEach((obj) => {
            this.$set(this.model, obj.prop, obj.multiple ? [] : "");
            if (val) {
              const object = deepClone(this.options[obj.index]);
              /*Object.keys(object.params).forEach(key => {
                if (!object.params[key]) {
                  object.params[key] = val
                }
              })*/
              object.params[obj.parentField] = val;
              this.$set(this.options, obj.index, object);
            }
            this.handlerCascade("", obj.prop);
          });
        }
      },
      // 初始化级联选项
      initCascadeOptions(val, key) {
        if (this.cascadeMap.has(key)) {
          const arr = this.cascadeMap.get(key);
          arr.forEach((obj) => {
            if (this.hasInitOptionsProps.includes(obj.prop)) return;
            if (val) {
              const object = deepClone(this.options[obj.index]);
              object.params[obj.parentField] = val;
              this.$set(this.options, obj.index, object);
              this.hasInitOptionsProps.push(obj.prop);
            }
          });
        }
      },
    },
    mounted() {
      //console.log('options:',this.options);
    }
  };
</script>


<style lang="scss" scoped>
  $border-color: #ebeef3;
  .page-form-container {
    font-size: 0;
    border-bottom: 1px solid $border-color;
    border-right: 1px solid $border-color;
    .el-form-item--small.el-form-item {
      margin-bottom: 0;
    }
    .el-form-item--small .el-form-item__content {
      line-height: inherit;
      font-size: inherit;
    }
    .el-form-item__error {
      padding-top: 1px;
      font-size: 10px;
      width: 100%;
    }
  }
  .rm-bottom-border {
    border-bottom: 0;
  }
  .no-border {
    border: 0;
  }
  .table-label{
    .require {
      display: inline-block;
      width: 8px;
      color: #f56c6c;
      vertical-align: -3px;
    }
  }
</style>
